<HTML>
<HEAD>
<TITLE>[Chapter 7] 7.5 CardLayout</TITLE>
<META NAME="author" CONTENT="John Zukowski">
<META NAME="date" CONTENT="Thu Jul 31 14:39:33 1997">
<META NAME="form" CONTENT="html">
<META NAME="metadata" CONTENT="dublincore.0.1">
<META NAME="objecttype" CONTENT="book part">
<META NAME="otheragent" CONTENT="gmat dbtohtml">
<META NAME="publisher" CONTENT="O'Reilly &amp; Associates, Inc.">
<META NAME="source" CONTENT="SGML">
<META NAME="subject" CONTENT="Java AWT">
<META NAME="title" CONTENT="Java AWT">
<META HTTP-EQUIV="Content-Script-Type" CONTENT="text/javascript">
</HEAD>
<body vlink="#551a8b" alink="#ff0000" text="#000000" bgcolor="#FFFFFF" link="#0000ee">

<DIV CLASS=htmlnav>
<H1><a href='index.htm'><IMG SRC="gifs/smbanner.gif"
     ALT="Java AWT" border=0></a></H1>
<table width=515 border=0 cellpadding=0 cellspacing=0>
<tr>
<td width=172 align=left valign=top><A HREF="ch07_04.htm"><IMG SRC="gifs/txtpreva.gif" ALT="Previous" border=0></A></td>
<td width=171 align=center valign=top><B><FONT FACE="ARIEL,HELVETICA,HELV,SANSERIF" SIZE="-1">Chapter 7<br>Layouts</FONT></B></TD>
<td width=172 align=right valign=top><A HREF="ch07_06.htm"><IMG SRC="gifs/txtnexta.gif" ALT="Next" border=0></A></td>
</tr>
</table>

&nbsp;
<hr align=left width=515>
</DIV>
<DIV CLASS=sect1>
<h2 CLASS=sect1><A CLASS="TITLE" NAME="JAWT-CH-7-SECT-5">7.5 CardLayout</A></h2>

<P CLASS=para>
<A NAME="CH07.CARD1"></A><A NAME="CH07.CARD2"></A><A NAME="CH07.CARD3"></A><A NAME="CH07.CARD4"></A>The <tt CLASS=literal>CardLayout</tt> layout manager 
is significantly different from the other layouts. Whereas the other layout 
managers attempt to display all the components within the container at 
once, a <tt CLASS=literal>CardLayout</tt> displays 
only one component at a time. (That component could be a <tt CLASS=literal>Component</tt> 
or another <tt CLASS=literal>Container</tt>.) The 
result is similar to Netscape Navigator's Property sheets or a tabbed 
Dialog, without the tabs. You can flip through the cards (components) in 
the layout in order or jump to a specific card if you know its name. The 
following call to <tt CLASS=literal>setLayout()</tt> 
changes the <tt CLASS=literal>LayoutManager</tt> of 
the current container to <tt CLASS=literal>CardLayout</tt>: 

<DIV CLASS=screen>
<P>
<PRE>
lm = new CardLayout();
setLayout (lm);
</PRE>
</DIV>

<P CLASS=para>
Unlike most other layout managers, <tt CLASS=literal>CardLayout</tt> 
has a number of instance methods that programs have to call. Therefore, 
you usually have to retain a reference to the layout manager. In addition, 
you usually have some other component to control the <tt CLASS=literal>CardLayout</tt> 
(i.e., select which card to view). Most simply, you could put some buttons 
in a panel and stick this panel in the north region of a <tt CLASS=literal>BorderLayout</tt>; 
then make another panel with a <tt CLASS=literal>CardLayout</tt>, 
and place that in the center. A more complex task would be to build a set 
of tabs to control the <tt CLASS=literal>CardLayout</tt>. 

<P CLASS=para>
A <tt CLASS=literal>CardLayout</tt> allows you to assign names to the components it manages. You 
can use the name to jump to an arbitrary component by calling the manager's 
<tt CLASS=literal>show()</tt> method. In Java 1.0, 
naming was optional; you could call <tt CLASS=literal>add(Component)</tt> 
to put a component in the layout with a null name. A null name meant 
only that you couldn't flip to the component at will; you could only display 
the component by calling <tt CLASS=literal>next()</tt> 
or <tt CLASS=literal>previous()</tt> (or <tt CLASS=literal>first()</tt> 
or <tt CLASS=literal>last()</tt>), which cycle through 
all the components in order. In Java 1.1, all components added to a <tt CLASS=literal>CardLayout</tt> 
must be named. 

<DIV CLASS=sect2>
<h3 CLASS=sect2><A CLASS="TITLE" NAME="JAWT-CH-7-SECT-5.1">CardLayout Methods</A></h3>Constructors

<P>
<DL CLASS=variablelist>
<DT CLASS=varlistentry><I CLASS=emphasis>public CardLayout () </I><br>
<DD>

<P CLASS=para>
This constructor creates a <tt CLASS=literal>CardLayout</tt> 
using a horizontal and vertical gap of zero pixels. With <tt CLASS=literal>CardLayout</tt>, 
there is no space between components because only one component is visible 
at a time; think of the gaps as insets. 

<p>
<DT CLASS=varlistentry><I CLASS=emphasis>public CardLayout (int hgap, int vgap) </I><br>
<DD>

<P CLASS=para>
This version of the constructor allows you to create a <tt CLASS=literal>CardLayout</tt> 
with a horizontal gap of <tt CLASS=literal>hgap</tt> 
and vertical gap of <tt CLASS=literal>vgap</tt> to 
add some space around the outside of the component that is displayed. The 
units for gaps are pixels. Using negative gaps chops off components at 
the edges of the container. </DL>
Informational methods

<P>
<DL CLASS=variablelist>
<DT CLASS=varlistentry><I CLASS=emphasis>public int getHgap () <img src="gifs/bstar.gif" alt="(New)" border=0> </I><br>
<DD>

<P CLASS=para>
The <tt CLASS=literal>getHgap()</tt> method retrieves 
the current horizontal gap setting. 

<p>
<DT CLASS=varlistentry><I CLASS=emphasis>public void setHgap (int hgap) <img src="gifs/bstar.gif" alt="(New)" border=0> </I><br>
<DD>

<P CLASS=para>
The <tt CLASS=literal>setHgap()</tt> method changes 
the current horizontal gap setting to <tt CLASS=literal>hgap</tt>. 
After changing the gaps, you must <tt CLASS=literal>validate()</tt> 
the <tt CLASS=literal>Container</tt>. 

<p>
<DT CLASS=varlistentry><I CLASS=emphasis>public int getVgap () <img src="gifs/bstar.gif" alt="(New)" border=0> </I><br>
<DD>

<P CLASS=para>
The <tt CLASS=literal>getVgap()</tt> method retrieves 
the current vertical gap setting. 

<p>
<DT CLASS=varlistentry><I CLASS=emphasis>public void setVgap (int hgap) <img src="gifs/bstar.gif" alt="(New)" border=0> </I><br>
<DD>

<P CLASS=para>
The <tt CLASS=literal>setVgap()</tt> method changes 
the current vertical gap setting to <tt CLASS=literal>vgap</tt>. 
After changing the gaps, you must <tt CLASS=literal>validate()</tt> 
the <tt CLASS=literal>Container</tt>. </DL>
LayoutManager methods

<P>
<DL CLASS=variablelist>
<DT CLASS=varlistentry><I CLASS=emphasis>public void addLayoutComponent (String name, Component component) <img src="gifs/wstar.gif" alt="(Deprecated)" border=0></I><br>
<DD>

<P CLASS=para>
This version of <tt CLASS=literal>addLayoutComponent()</tt> 
has been deprecated and replaced by the <tt CLASS=literal>addLayoutComponent(Component, 
Object)</tt> method of the <tt CLASS=literal>LayoutManager2</tt> 
interface. 

<p>
<DT CLASS=varlistentry><I CLASS=emphasis>public void removeLayoutComponent (Component component)  </I><br>
<DD>

<P CLASS=para>
The <tt CLASS=literal>removeLayoutComponent()</tt> 
method of <tt CLASS=literal>CardLayout</tt> removes 
<tt CLASS=literal>component</tt> from the container. 
If <tt CLASS=literal>component</tt> is not in the 
container already, nothing happens. 

<p>
<DT CLASS=varlistentry><I CLASS=emphasis>public Dimension preferredLayoutSize (Container target)  </I><br>
<DD>

<P CLASS=para>
The <tt CLASS=literal>preferredLayoutSize()</tt> method 
of <tt CLASS=literal>CardLayout</tt> retrieves the 
preferred size for all the components within it. The <tt CLASS=literal>preferredLayoutSize()</tt> 
method then determines the widest and tallest size of all components (not 
necessarily from the same one), adds the appropriate insets and gaps, and 
uses that as the preferred size for the layout. 

<p>
<DT CLASS=varlistentry><I CLASS=emphasis>public Dimension minimumLayoutSize (Container target)  </I><br>
<DD>

<P CLASS=para>
The <tt CLASS=literal>minimumLayoutSize()</tt> method 
of <tt CLASS=literal>CardLayout</tt> calculates the 
minimum size for all the components within it. The <tt CLASS=literal>minimumLayoutSize()</tt> 
method then determines the widest and tallest minimum size of all components 
(not necessarily from the same one), adds the appropriate insets and gaps, 
and uses that as the minimum size for the layout. 

<p>
<DT CLASS=varlistentry><I CLASS=emphasis>public void layoutContainer (Container target)  </I><br>
<DD>

<P CLASS=para>
The <tt CLASS=literal>layoutContainer()</tt> method 
draws <tt CLASS=literal>target</tt>'s visible 
components one on top of another. Initially, all components are visible. 
Components do not become invisible until you select one for display, by 
calling the <tt CLASS=literal>first()</tt>, <tt CLASS=literal>last()</tt>, 
<tt CLASS=literal>next()</tt>, <tt CLASS=literal>previous()</tt>, 
or <tt CLASS=literal>show()</tt> methods. Where possible, 
<tt CLASS=literal>CardLayout</tt> reshapes all components 
to fit the target container. </DL>
LayoutManager2 methods

<P>
<DL CLASS=variablelist>
<DT CLASS=varlistentry><I CLASS=emphasis>public void addLayoutComponent (Component component, Object name) <img src="gifs/bstar.gif" alt="(New)" border=0> </I><br>
<DD>

<P CLASS=para>
This <tt CLASS=literal>addLayoutComponent()</tt> method 
of <tt CLASS=literal>CardLayout</tt> puts <tt CLASS=literal>component</tt> 
into an internal table with a key of <tt CLASS=literal>name</tt>. 
The <tt CLASS=literal>name</tt> comes from the version 
of <tt CLASS=literal>add()</tt> that has a constraints 
object as a parameter. The name allows you to refer to the component when 
you call other card layout methods, like <tt CLASS=literal>show()</tt>. 
If you call the version of <tt CLASS=literal>add()</tt> 
that only takes a <tt CLASS=literal>Component</tt> 
parameter, you cannot call the <tt CLASS=literal>show()</tt> 
method to flip to the specific component. 

<P CLASS=para>
If <tt CLASS=literal>name</tt> is not a <tt CLASS=literal>String</tt>, 
the run-time exception <tt CLASS=literal>IllegalArgumentException</tt> 
is thrown. 

<p>
<DT CLASS=varlistentry><I CLASS=emphasis>public abstract Dimension maximumLayoutSize(Container target) <img src="gifs/bstar.gif" alt="(New)" border=0> </I><br>
<DD>

<P CLASS=para>
The <tt CLASS=literal>maximumLayoutSize()</tt> method 
returns a <tt CLASS=literal>Dimension</tt> object 
with a width and height of <tt CLASS=literal>Integer.MAX_VALUE</tt>. 
In practice, this means that <tt CLASS=literal>CardLayout</tt> 
doesn't support the concept of maximum size. 

<p>
<DT CLASS=varlistentry><I CLASS=emphasis>public abstract float getLayoutAlignmentX(Container target) <img src="gifs/bstar.gif" alt="(New)" border=0> </I><br>
<DD>

<P CLASS=para>
The <tt CLASS=literal>getLayoutAlignmentX()</tt> method 
says that <tt CLASS=literal>CardLayout</tt> containers 
should be centered horizontally within the area available. 

<p>
<DT CLASS=varlistentry><I CLASS=emphasis>public abstract float getLayoutAlignmentY(Container target) <img src="gifs/bstar.gif" alt="(New)" border=0> </I><br>
<DD>

<P CLASS=para>
The <tt CLASS=literal>getLayoutAlignmentY()</tt> method 
says that <tt CLASS=literal>CardLayout</tt> containers 
should be centered vertically within the area available. 

<p>
<DT CLASS=varlistentry><I CLASS=emphasis>public abstract void invalidateLayout(Container target) <img src="gifs/bstar.gif" alt="(New)" border=0> </I><br>
<DD>

<P CLASS=para>
The <tt CLASS=literal>invalidateLayout()</tt> method 
of <tt CLASS=literal>CardLayout</tt> does nothing. </DL>
CardLayout methods

<P CLASS=para>
This group of methods controls which component the <tt CLASS=literal>CardLayout</tt> 
displays. The <tt CLASS=literal>show()</tt> is only 
usable if you assigned components names when adding them to the container. 
The others can be used even if the components are unnamed; they cycle through 
the components in the order in which they were added. All of these methods 
require the parent <tt CLASS=literal>Container</tt> 
(i.e., the container being managed by this layout manager) as an argument. 
If the layout manager of the <tt CLASS=literal>parent</tt> 
parameter is anything other than the container using this instance of the 
<tt CLASS=literal>CardLayout</tt>, the method throws 
the run-time exception <tt CLASS=literal>IllegalArgumentException</tt>. 

<P>
<DL CLASS=variablelist>
<DT CLASS=varlistentry><I CLASS=emphasis>public void first (Container parent) </I><br>
<DD>

<P CLASS=para>
The <tt CLASS=literal>first()</tt> method flips to 
the initial component in <tt CLASS=literal>parent</tt>. 

<p>
<DT CLASS=varlistentry><I CLASS=emphasis>public void next (Container parent) </I><br>
<DD>

<P CLASS=para>
The <tt CLASS=literal>next()</tt> method flips to 
the following component in <tt CLASS=literal>parent</tt>, 
wrapping back to the beginning if the current component is the last. 

<p>
<DT CLASS=varlistentry><I CLASS=emphasis>public void previous (Container parent) </I><br>
<DD>

<P CLASS=para>
The <tt CLASS=literal>previous()</tt> method flips 
to the prior component in <tt CLASS=literal>parent</tt>, 
wrapping to the end if the current component is the first. 

<p>
<DT CLASS=varlistentry><I CLASS=emphasis>public void last (Container parent) </I><br>
<DD>

<P CLASS=para>
The <tt CLASS=literal>last()</tt> method flips to 
the final component in <tt CLASS=literal>parent</tt>. 

<p>
<DT CLASS=varlistentry><I CLASS=emphasis>public void show (Container parent, String name) </I><br>
<DD>

<P CLASS=para>
The <tt CLASS=literal>show()</tt> method displays 
the component in parent that was assigned the given <tt CLASS=literal>name</tt> 
when it was added to the container. If there is no component with <tt CLASS=literal>name</tt> 
contained within <tt CLASS=literal>parent</tt>, nothing 
happens. </DL>
Miscellaneous methods

<P>
<DL CLASS=variablelist>
<DT CLASS=varlistentry><I CLASS=emphasis>public String toString () </I><br>
<DD>

<P CLASS=para>
The <tt CLASS=literal>toString()</tt> method of <tt CLASS=literal>CardLayout</tt> 
returns the a string showing the current horizontal and vertical gap settings. 
The result for a typical <tt CLASS=literal>CardLayout</tt> 
would be: </DL>
<DIV CLASS=screen>
<P>
<PRE>
java.awt.CardLayout[hgap=0,vgap=0]
</PRE>
</DIV>

</DIV>

<DIV CLASS=sect2>
<h3 CLASS=sect2><A CLASS="TITLE" NAME="JAWT-CH-7-SECT-5.2">CardLayout Example</A></h3>

<P CLASS=para>
<A HREF="ch07_05.htm#JAWT-CH-7-FIG-7">Figure 7.7</A> shows a simple <tt CLASS=literal>CardLayout</tt>. 
This layout has three cards that cycle when you make a selection. 
The first card (A) contains some <tt CLASS=literal>Checkbox</tt> 
items within a <tt CLASS=literal>Panel</tt>, the second 
card (B) contains a single <tt CLASS=literal>Button</tt>, 
and the third (C) contains a <tt CLASS=literal>List</tt> 
and a <tt CLASS=literal>Choice</tt> within another 
<tt CLASS=literal>Panel</tt>. 

<DIV CLASS=figure>
<h4 CLASS=figure><A CLASS="TITLE" NAME="JAWT-CH-7-FIG-7">Figure 7.7: Different views of CardLayout</A></h4>


<p>
<img align=middle src="./figs/jawt0707.gif" alt="[Graphic: Figure 7-7]" width=503 height=217 border=0>

</DIV>

<P CLASS=para>
<A HREF="ch07_05.htm#JAWT-CH-7-EX-1">Example 7.1</A> is the code that generated <A HREF="ch07_05.htm#JAWT-CH-7-FIG-7">Figure 7.7</A>.

<DIV CLASS=example>
<h4 CLASS=example><A CLASS="TITLE" NAME="JAWT-CH-7-EX-1">Example 7.1: The CardExample Class</A></h4>

<DIV CLASS=screen>
<P>
<PRE>
import java.awt.*;
import java.applet.*;
public class CardExample extends Applet {
    CardLayout cl = new CardLayout();
    public void init () {
        String fonts[] = Toolkit.getDefaultToolkit().getFontList();
        setLayout (cl);
        Panel pA = new Panel();
        Panel pC = new Panel ();
        p1.setLayout (new GridLayout (3, 2));
        List l = new List(4, false);
        Choice c = new Choice ();
        for (int i=0;i&lt;fonts.length;i++) {
            pA.add (new Checkbox (fonts[i]));
            l.addItem (fonts[i]);
            c.addItem (fonts[i]);
        }
        pC.add (l);
        pC.add (c);
        add ("One", pA);
        add ("Two", new Button ("Click Here"));
        add ("Three", pC);
    }
    public boolean action (Event e, Object o) {
        cl.next(this);
        return true;
    }
}
</PRE>
</DIV>

</DIV>

<P CLASS=para>
Each panel within the <tt CLASS=literal>CardLayout</tt> 
has its own layout manager. <tt CLASS=literal>Panel</tt> 
A uses a <tt CLASS=literal>GridLayout</tt>; panel C uses its default layout manager, which is a <tt CLASS=literal>FlowLayout</tt>. 
When the user takes any action (i.e., clicking on a checkbox or button, 
or selecting an item from the <tt CLASS=literal>List</tt> 
or <tt CLASS=literal>Choice</tt> components), the 
system generates a call to <tt CLASS=literal>action()</tt>, 
which calls the <tt CLASS=literal>CardLayout</tt>'s 
<tt CLASS=literal>next()</tt> method, thus displaying 
the next card in the sequence. 

</DIV>

</DIV>


<DIV CLASS=htmlnav>

<P>
<HR align=left width=515>
<table width=515 border=0 cellpadding=0 cellspacing=0>
<tr>
<td width=172 align=left valign=top><A HREF="ch07_04.htm"><IMG SRC="gifs/txtpreva.gif" ALT="Previous" border=0></A></td>
<td width=171 align=center valign=top><a href="index.htm"><img src='gifs/txthome.gif' border=0 alt='Home'></a></td>
<td width=172 align=right valign=top><A HREF="ch07_06.htm"><IMG SRC="gifs/txtnexta.gif" ALT="Next" border=0></A></td>
</tr>
<tr>
<td width=172 align=left valign=top>GridLayout</td>
<td width=171 align=center valign=top><a href="index/idx_a.htm"><img src='gifs/index.gif' alt='Book Index' border=0></a></td>
<td width=172 align=right valign=top>GridBagLayout</td>
</tr>
</table>
<hr align=left width=515>

<IMG SRC="gifs/smnavbar.gif" USEMAP="#map" BORDER=0> 
<MAP NAME="map"> 
<AREA SHAPE=RECT COORDS="0,0,108,15" HREF="../javanut/index.htm"
alt="Java in a Nutshell"> 
<AREA SHAPE=RECT COORDS="109,0,200,15" HREF="../langref/index.htm" 
alt="Java Language Reference"> 
<AREA SHAPE=RECT COORDS="203,0,290,15" HREF="../awt/index.htm" 
alt="Java AWT"> 
<AREA SHAPE=RECT COORDS="291,0,419,15" HREF="../fclass/index.htm" 
alt="Java Fundamental Classes"> 
<AREA SHAPE=RECT COORDS="421,0,514,15" HREF="../exp/index.htm" 
alt="Exploring Java"> 
</MAP>
</DIV>

</BODY>
</HTML>
